package com.patchmanage.back.service.impl;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.ShearCaptcha;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Console;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.patchmanage.back.annotation.LoginValidate;
import com.patchmanage.back.config.Constants;
import com.patchmanage.back.entity.Admin;
import com.patchmanage.back.entity.DepartmentGroup;
import com.patchmanage.back.entity.Role;
import com.patchmanage.back.entity.SafeConfig;
import com.patchmanage.back.exception.SystemException;
import com.patchmanage.back.mapper.AdminMapper;
import com.patchmanage.back.redis.JedisTemplate;
import com.patchmanage.back.result.CodeMsg;
import com.patchmanage.back.service.IAdminService;
import com.patchmanage.back.service.IDepartmentGroupService;
import com.patchmanage.back.service.IRoleService;
import com.patchmanage.back.service.ISafeConfigService;
import com.patchmanage.back.utils.MD5Util;
import com.patchmanage.back.utils.UUIDUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author huizhao
 * @since 2021-03-20
 */
@Service
public class AdminServiceImpl extends ServiceImpl<AdminMapper, Admin> implements IAdminService {

    @Autowired
    private JedisTemplate<String> jedisTemplate;

    @Autowired
    private IRoleService roleService;

    @Autowired
    private IDepartmentGroupService departmentGroupService;

    @Autowired
    private ISafeConfigService safeConfigService;

    /**
     * @describe：登录   @author：HuiZhao  
     *
     * @createTime：2019年10月11日 下午3:23:23
     * @param dict
     * @return token
     */
    public Dict login(Dict dict) {

        if (dict.get("username") == null || (dict.get("password") == null)) {
            throw new SystemException(CodeMsg.BIND_ERROR);
        }

        /*if (dict.get("verificationCode") != null) {
             *//** 验证码不为空 校验验证码**//*
             if(checkVerificationCode(dict) == false){
                 throw new SystemException(CodeMsg.ACCOUNT_VERIFICATION_CODE_ERROR);
             };
        }*/

        /** 获取密码安全策略设置**/
        SafeConfig safeConfig = safeConfigService.getById(1);
        int maxErrorLoginNum = 0;
        int errorLockTime = 0;
        int maxSessionTime = 0;
        if(safeConfig != null){
            maxErrorLoginNum = safeConfig.getMaxErrorLoginNum();
            errorLockTime = safeConfig.getErrorLockTime();
            maxSessionTime = safeConfig.getMaxSessionTime();
        }


        /** 验证账号密码 **/
        QueryWrapper<Admin> queryWrapper = new QueryWrapper<Admin>();
        queryWrapper.eq("username", dict.getStr("username"));
        queryWrapper.eq("password", MD5Util.md5(dict.getStr("password")));
        Admin users = getOne(queryWrapper);
        if (users == null) {
            if(maxErrorLoginNum != 0 && errorLockTime != 0){
                //登录错误统计
                jedisTemplate.incr(Constants.LOGIN_ERROR_COUNT + dict.get("username"));
                jedisTemplate.expire(Constants.LOGIN_ERROR_COUNT,300);

                String loginErrorCodeCount = jedisTemplate.get(Constants.LOGIN_ERROR_COUNT + dict.get("username"));

                if(Integer.valueOf(loginErrorCodeCount) > maxErrorLoginNum){
                    //锁定账号
                    jedisTemplate.setex(Constants.LOGIN_USER_LOCK + dict.get("username"), dict.get("username"),(errorLockTime * 60));
                    //删除登录错误统计
                    jedisTemplate.del(Constants.LOGIN_ERROR_COUNT + dict.get("username"));
                }
            }
            throw new SystemException(CodeMsg.ACCOUNT_PASSWORD_ERROR);
        }


        /** 判断账号是否是锁定中 **/
        String userLock = jedisTemplate.get(Constants.LOGIN_USER_LOCK + dict.get("username"));
        if(StrUtil.isNotBlank(userLock)){
            throw new SystemException(CodeMsg.ACCOUNT_LOCK_ERROR);
        }


        /** 账号密码验证成功 **/
        jedisTemplate.del(Constants.LOGIN_ERROR_COUNT + dict.get("username"));
        jedisTemplate.del(Constants.LOGIN_ERROR_COUNT + dict.get("username"));

        String token = UUIDUtil.uuid();
        Dict returnDict = new Dict();
        if(maxSessionTime == 0){
            jedisTemplate.set(Constants.userToken + token, users.getId().toString());
        }else{
            jedisTemplate.setex(Constants.userToken + token, users.getId().toString(), (maxSessionTime * 60));
        }
        returnDict.put("token", token);
        returnDict.put("user", users);
        return returnDict;
    }

    /**
     * 校验验证码
     *
     * @param dict 参数
     * @return
     */
    public Boolean checkVerificationCode(Dict dict) {

        String verificationCodeParam = dict.getStr("verificationCode");

        /** 校验参数 **/
        if (StrUtil.isBlank(verificationCodeParam)) {
            throw new SystemException(CodeMsg.BIND_ERROR);
        }

        String verificationCodeRedis = jedisTemplate.get(Constants.loginVerifyCode);
        if (StrUtil.isBlank(verificationCodeRedis) || !(verificationCodeParam.equals(verificationCodeRedis))) {
            return false;
        }
        return true;
    }


    /**
     * @describe：通过token得到user   @author：HuiZhao  
     *
     * @createTime：2019年10月11日 下午3:23:23
     * @param dict
     * @return user
     */
    public Admin getByToken(Dict dict) {
        if (StrUtil.isBlank(dict.getStr("token"))) {
            return null;
        }

        String userId = jedisTemplate.get(Constants.userToken + dict.getStr("token"));
        Admin admin =  getById(userId);
        if(admin == null){
            return null;
        }
        admin.setPassword(null);
        jedisTemplate.expire(Constants.userToken + dict.getStr("token"),1800);
        return admin;
    }

    /**
     * @describe：注册   @author：HuiZhao  
     *
     * @createTime：2019年10月11日 下午3:23:23
     * @param entity
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean registe(Admin entity) {

        QueryWrapper<Admin> queryWrapper = new QueryWrapper<Admin>();
        queryWrapper.eq("username", entity.getUsername());
        int count = count(queryWrapper);
        if (count > 0) {
            throw new SystemException(CodeMsg.LOGIN_NAME_EXIST);
        }
        entity.setPassword(MD5Util.md5(entity.getPassword()));

        if(entity.getRole() != null){
           Role role = roleService.getById(entity.getRole());
            if(role != null){
                entity.setRoleName(role.getName());
            }
        }

        if(entity.getDepartmentGroupIds().equals("all")){
            List<DepartmentGroup> departmentGroupList =  departmentGroupService.list();
            if(departmentGroupList.size() > 0){
                List<Object> ids = CollUtil.getFieldValues(departmentGroupList, "id");
                entity.setDepartmentGroupIds(ids.toArray().toString());
            }
        }
        return save(entity);
    }

    /**
     * 设置新密码
     *
     * @param dict 1 登录 2找回密码
     * @param dict
     * @return
     */
    @LoginValidate
    @Transactional(rollbackFor = Exception.class)
    public Boolean setNewPassword(Dict dict) {

        String username = dict.getStr("username");
        String password = dict.getStr("password");
        String password1 = dict.getStr("password1");

        /** 校验参数 **/
        if ( StrUtil.isBlank(username) || StrUtil.isBlank(password) || StrUtil.isBlank(password1)) {
            throw new SystemException(CodeMsg.BIND_ERROR);
        }

        QueryWrapper<Admin> queryWrapper = new QueryWrapper<Admin>();
        queryWrapper.eq("username",username);
        queryWrapper.eq("password", MD5Util.md5(password));
        Integer count = count(queryWrapper);
        if(count == 0){
            throw new SystemException(CodeMsg.PASSWORD_ERROR);
        }

        /** 修改密码 **/
        Admin user = new Admin();
        user.setPassword(SecureUtil.md5(password1));
        UpdateWrapper<Admin> updateWrapper = new UpdateWrapper<Admin>();
        updateWrapper.eq("username", username);
        update(user, updateWrapper);
        return true;
    }

    public void getVerifyCode(HttpServletRequest request, HttpServletResponse response) throws IOException{
        ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(250, 100, 4, 4);
        Console.log(captcha.getCode());
        jedisTemplate.setex(Constants.loginVerifyCode,captcha.getCode(),3000);
        captcha.write(response.getOutputStream());
    }
}
